<?php

namespace app\common\library;

/**
 * 音频处理辅助类
 */
class AudioHelper
{
    /**
     * 获取音频文件时长（秒）
     * @param string $filePath 音频文件路径
     * @return int 时长（秒），失败返回0
     */
    public static function getAudioDuration($filePath)
    {
        try {
            // 方法1：尝试使用FFmpeg（优先使用，因为最准确）
            if (self::isFFmpegAvailable()) {
                $duration = self::getDurationWithFFmpeg($filePath);
                if ($duration > 0) {
                    return $duration;
                }
            }
            
            // 方法2：尝试使用getID3库（如果存在）
            if (class_exists('\getID3')) {
                $duration = self::getDurationWithGetID3($filePath);
                if ($duration > 0) {
                    return $duration;
                }
            }
            
            // 方法3：尝试读取音频文件头信息
            $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
            if ($extension === 'mp3') {
                $duration = self::getMp3DurationFromHeader($filePath);
                if ($duration > 0) {
                    return $duration;
                }
            }
            
            // 方法4：基于文件大小的估算（最后的备用方案）
            return self::estimateDurationByFileSize($filePath);
            
        } catch (\Exception $e) {
            // 出现异常时，基于文件大小估算
            return self::estimateDurationByFileSize($filePath);
        }
    }

    /**
     * 使用getID3库获取音频时长
     */
    private static function getDurationWithGetID3($filePath)
    {
        try {
            $getID3 = new \getID3;
            $fileInfo = $getID3->analyze($filePath);
            
            if (isset($fileInfo['playtime_seconds'])) {
                return (int) round($fileInfo['playtime_seconds']);
            }
            
            return 0;
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * 使用FFmpeg获取音频时长
     */
    private static function getDurationWithFFmpeg($filePath)
    {
        try {
            $command = "ffprobe -i " . escapeshellarg($filePath) . " -show_entries format=duration -v quiet -of csv=\"p=0\" 2>&1";
            $output = shell_exec($command);
            
            if ($output && is_numeric(trim($output))) {
                return (int) round((float) trim($output));
            }
            
            return 0;
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * 检查FFmpeg是否可用
     */
    private static function isFFmpegAvailable()
    {
        try {
            $output = shell_exec('ffprobe -version 2>&1');
            return strpos($output, 'ffprobe') !== false;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * 通过读取MP3文件头获取时长
     */
    private static function getMp3DurationFromHeader($filePath)
    {
        try {
            if (!file_exists($filePath) || !is_readable($filePath)) {
                return 0;
            }
            
            $file = fopen($filePath, 'rb');
            if (!$file) {
                return 0;
            }
            
            $duration = 0;
            $bitrate = 0;
            $fileSize = filesize($filePath);
            
            // 读取文件头，查找MPEG帧
            fseek($file, 0);
            $header = fread($file, 4096);
            fclose($file);
            
            // 查找MPEG帧同步字节 (0xFF)
            for ($i = 0; $i < strlen($header) - 4; $i++) {
                if (ord($header[$i]) == 0xFF && (ord($header[$i + 1]) & 0xE0) == 0xE0) {
                    // 找到MPEG帧头，解析比特率
                    $mpegVersion = (ord($header[$i + 1]) & 0x18) >> 3;
                    $layer = (ord($header[$i + 1]) & 0x06) >> 1;
                    $bitrateIndex = (ord($header[$i + 2]) & 0xF0) >> 4;
                    
                    // 获取比特率（简化版本）
                    $bitrates = [
                        // MPEG-1 Layer III
                        [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0],
                        // 其他版本的比特率表可以继续添加
                    ];
                    
                    if ($bitrateIndex > 0 && $bitrateIndex < 15) {
                        $bitrate = $bitrates[0][$bitrateIndex] ?? 128;
                        if ($bitrate > 0) {
                            // 计算时长：文件大小(字节) * 8 / 比特率(kbps) / 1000
                            $duration = ($fileSize * 8) / ($bitrate * 1000);
                            break;
                        }
                    }
                }
            }
            
            return (int) round($duration);
            
        } catch (\Exception $e) {
            return 0;
        }
    }

    /**
     * 基于文件大小估算音频时长
     */
    private static function estimateDurationByFileSize($filePath)
    {
        try {
            if (!file_exists($filePath)) {
                return 0;
            }
            
            $fileSize = filesize($filePath);
            if ($fileSize <= 0) {
                return 0;
            }
            
            $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
            
            // 根据不同格式设置不同的估算比特率
            $estimatedBitrate = 128; // 默认128kbps
            
            switch ($extension) {
                case 'mp3':
                    $estimatedBitrate = 128; // MP3平均比特率
                    break;
                case 'wav':
                    $estimatedBitrate = 1411; // WAV无压缩，比特率很高
                    break;
                case 'm4a':
                case 'aac':
                    $estimatedBitrate = 128; // AAC/M4A平均比特率
                    break;
            }
            
            // 计算估算时长
            $duration = ($fileSize * 8) / ($estimatedBitrate * 1000);
            
            return (int) round($duration);
            
        } catch (\Exception $e) {
            return 30; // 异常时返回默认30秒
        }
    }

    /**
     * 格式化音频时长为 mm:ss 格式
     */
    public static function formatDuration($seconds)
    {
        if ($seconds <= 0) {
            return '0:00';
        }
        
        $minutes = floor($seconds / 60);
        $seconds = $seconds % 60;
        
        return sprintf('%d:%02d', $minutes, $seconds);
    }

    /**
     * 验证音频文件格式
     */
    public static function validateAudioFormat($filePath, $allowedFormats = ['mp3', 'wav', 'm4a', 'aac'])
    {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        return in_array($extension, $allowedFormats);
    }

    /**
     * 获取音频文件的基本信息
     */
    public static function getAudioInfo($filePath)
    {
        $info = [
            'duration' => 0,
            'bitrate' => 0,
            'sample_rate' => 0,
            'channels' => 0,
            'format' => '',
            'size' => 0
        ];

        try {
            if (file_exists($filePath)) {
                $info['size'] = filesize($filePath);
                $info['format'] = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
                $info['duration'] = self::getAudioDuration($filePath);
            }
        } catch (\Exception $e) {
            // 静默处理错误
        }

        return $info;
    }
}
